package com.aliyun.oss.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
@Component
//封装httpclient的get,post请求
public class HttpClientUtil {
    //    JSON工具转换类
    private static final ObjectMapper objectMapper = new ObjectMapper();
    // 默认连接超时时间（毫秒）
    private static final int DEFAULT_CONNECT_TIMEOUT = 5000;
    // 默认socket超时时间（毫秒）
    private static final int DEFAULT_SOCKET_TIMEOUT = 10000;

    /**
     * 关闭资源
     *
     * @param response   HTTP响应
     * @param httpClient HTTP客户端
     */
    private static void closeResources(CloseableHttpResponse response, CloseableHttpClient httpClient) {
        try {
            if (response != null) response.close();
            if (httpClient != null) httpClient.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * GET请求
     *
     * @param url           请求URL
     * @param paramMap      请求参数
     * @param authorization 认证信息
     * @return 响应字符串
     */
    public static String doGet(String url, Map<String, String> paramMap, String authorization) {
        return doGet(url, paramMap, authorization, null);
    }

    /**
     * GET请求
     *
     * @param url           请求URL
     * @param paramMap      请求参数
     * @param authorization 认证信息
     * @param headers       请求头
     * @return 响应字符串
     */
    public static String doGet(String url, Map<String, String> paramMap, String authorization, Map<String, String> headers) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = null;
        CloseableHttpResponse response = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            if (paramMap != null) {
                for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                    uriBuilder.addParameter(entry.getKey(), entry.getValue());
                }
            }
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            // 设置认证头
            if (authorization != null && !authorization.trim().isEmpty()) {
                httpGet.setHeader("Authorization", authorization);
            }
            // 设置其他请求头
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpGet.setHeader(entry.getKey(), entry.getValue());
                }
            }
            // 设置超时配置
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(DEFAULT_CONNECT_TIMEOUT).setSocketTimeout(DEFAULT_SOCKET_TIMEOUT).build();
            httpGet.setConfig(requestConfig);
            // 执行请求
            response = httpClient.execute(httpGet);
            // 检查响应状态
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity, "UTF-8");
            } else {
                throw new RuntimeException("HTTP GET请求失败，状态码: " + statusCode);
            }
        } catch (URISyntaxException e) {
            throw new RuntimeException("URL格式错误: " + url, e);
        } catch (ClientProtocolException e) {
            throw new RuntimeException("HTTP协议错误", e);
        } catch (IOException e) {
            throw new RuntimeException("网络IO错误", e);
        } finally {
            closeResources(response, httpClient);
        }
        return result;
    }

    /**
     * 简单的GET请求（无参数和认证）
     *
     * @param url 请求URL
     * @return 响应字符串
     */
    public static String doGet(String url) {
        return doGet(url, null, null);
    }

    /**
     * POST请求 - JSON格式（适合@RequestBody接收）
     *
     * @param url           请求URL
     * @param jsonData      JSON字符串
     * @param authorization 认证信息
     * @return 响应字符串
     */
    public static String doPost(String url, String jsonData, String authorization) {
        return doPost(url, jsonData, authorization, null);
    }

    /**
     * POST请求 - JSON格式（适合@RequestBody接收）
     *
     * @param url           请求URL
     * @param jsonData      JSON字符串
     * @param authorization 认证信息
     * @param headers       请求头
     * @return 响应字符串
     */
    public static String doPost(String url, String jsonData, String authorization, Map<String, String> headers) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost();
            if (jsonData != null) {
                StringEntity entity = new StringEntity(jsonData, ContentType.APPLICATION_JSON);
                httpPost.setEntity(entity);
            }
            // 设置认证头
            if (authorization != null && !authorization.trim().isEmpty()) {
                httpPost.setHeader("Authorization", authorization);
            }
            // 设置其他请求头
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }
            // 设置超时配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(DEFAULT_CONNECT_TIMEOUT)
                    .setSocketTimeout(DEFAULT_SOCKET_TIMEOUT)
                    .build();
            httpPost.setConfig(requestConfig);
            // 执行请求
            response = httpClient.execute(httpPost);
            // 检查响应状态
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity, "UTF-8");
            } else {
                throw new RuntimeException("HTTP POST请求失败，状态码: " + statusCode);
            }
        } catch (ClientProtocolException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            closeResources(response, httpClient);
        }
        return result;
    }

    /**
     * POST请求 - 支持Map参数自动转JSON
     *
     * @param url           请求URL
     * @param paramMap      参数Map（自动转换为JSON）
     * @param authorization 认证信息
     * @return 响应字符串
     */
    public static String doPost(String url, Map<String, Object> paramMap, String authorization) {
        try {
            String jsonData = mapToJson(paramMap);
            return doPost(url, jsonData, authorization);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("参数转换JSON失败", e);
        }
    }

    private static String mapToJson(Map<String, Object> paramMap) throws JsonProcessingException {
        if (paramMap == null) {
            return "{}";
        }
        return objectMapper.writeValueAsString(paramMap);
    }

    /**
     * POST请求 - 支持Map参数自动转JSON
     *
     * @param url           请求URL
     * @param paramMap      参数Map（自动转换为JSON）
     * @param authorization 认证信息
     * @param headers       请求头
     * @return 响应字符串
     */
    public static String doPost(String url, Map<String, Object> paramMap, String authorization,
                                Map<String, String> headers) {
        try {
            String jsonData = mapToJson(paramMap);
            return doPost(url, jsonData, authorization, headers);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("参数转换JSON失败", e);
        }
    }
    public static String doPost(String url, Object requestObject, String authorization) {
        try {
            String string = objectMapper.writeValueAsString(requestObject);
            return doPost(url, string, authorization);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

